<template>
  <el-input v-model="folderDir" class="hideinput"></el-input>
  <!-- 编辑新增模块 -->
  <div class="wrap" ref="wrapRef" v-if="!isExhibition">
    <div class="wrap_l" ref="wraplRef" :class="fileNum.length >= limit && isTableLine ? 'wrap_lnone' : ''">
      <input
        type="file"
        :disabled="loadingFlag"
        :id="'fileInputBtn' + MathNum"
        title
        :class="fileNum.length < limit ? 'fileInput' : 'fileInput porfileInput'"
      />
      <template v-if="fileNum.length < limit">
        <el-button type="primary" plain v-if="!loadingFlag" :disabled="disabled ? true : false">{{ t('keys.uploaFile') }}</el-button>
        <el-button :loading="true" disabled v-else>{{ t('keys.uploading') }}</el-button>
      </template>
      <template v-else>
        <el-button disabled>{{ t('keys.uploaFile') }}</el-button>
      </template>
    </div>

    <div ref="wrapr" class="wrap_r" :style="{ width: wraprWidth }" v-if="fileList.length != 0 && fileList.length <= 1">
      <!-- 附件上限数量等于1时，上传后，按钮⽂字变为“重新上传”，重新上传后对已上传附件进⾏替换； -->
      <div class="singleGroup" v-for="(item, i) in fileList" :key="i">
        <div class="singleGroup_l" :class="item.uploadFlag ? 'errcolor' : ''">{{ item.name }}</div>
        <div class="singleGroup_r" :class="item.loadingIconFlag ? 'showsingleGroup' : ''">
          <el-icon v-if="item.loadingIconFlag"><Loading /></el-icon>
          <a v-if="item.downloadIconFlag" :href="getFileBucketDirObject(item.meta.dir, item.meta.name)" class="down_upload_template" target="_blank">
            <el-icon><Download /></el-icon>
          </a>
          <el-icon v-if="item.uploadFlag" @click.stop="uploadClick(item)" class="el-icon-upload2" :class="item.uploadFlag ? 'errcolor' : ''"
            ><Upload
          /></el-icon>
          <el-icon @click.stop="getFileBucketDirDele(item)" :class="item.uploadFlag ? 'errcolor' : ''" v-if="item.deleIconFlag"><Delete /></el-icon>
        </div>
      </div>
    </div>
    <!-- 附件上限数量⼤于1时，上传到达上限前按钮不变，到达上限后按钮变为失效状态，删除已上传附件后恢复； -->
    <div class="wrap_r" v-if="fileList.length > 1" @mouseover="overShow" @mouseout="outHide">
      <div class="inputtxt" @click.stop="showList = !showList">
        <div class="inputtxt_l">{{ t('keys.hasUploaded') }} ({{ fileNum.length }})</div>
        <div class="inputtxt_r">
          <el-icon v-if="!loadingFlag" class="inputtxt_r_icon el-icon-arrow-up" :class="showList ? 'isReverse' : ''"><ArrowDown /></el-icon>
          <el-icon v-if="loadingFlag"><Loading /></el-icon>
        </div>
      </div>
      <el-collapse-transition>
        <div class="ullist" v-show="showList">
          <!-- 附件上限数量等于1时，上传后，按钮⽂字变为“重新上传”，重新上传后对已上传附件进⾏替换； -->
          <div class="singleGroup" v-for="(item, i) in fileList" :key="i">
            <div class="singleGroup_l" :class="item.uploadFlag ? 'errcolor' : ''">{{ item.name }}</div>
            <div class="singleGroup_r" :class="item.loadingIconFlag ? 'showsingleGroup' : ''">
              <el-icon v-if="item.loadingIconFlag"><Loading /></el-icon>
              <a
                v-if="item.downloadIconFlag"
                :href="getFileBucketDirObject(item.meta.dir, item.meta.name)"
                class="down_upload_template"
                target="_blank"
              >
                <el-icon><Download /></el-icon>
              </a>
              <el-icon v-if="item.uploadFlag" @click.stop="uploadClick(item)" class="el-icon-upload2" :class="item.uploadFlag ? 'errcolor' : ''"
                ><Upload
              /></el-icon>
              <el-icon
                @click.stop="getFileBucketDirDele(item)"
                class="el-icon-delete dele"
                :class="item.uploadFlag ? 'errcolor' : ''"
                v-if="item.deleIconFlag"
                ><Delete
              /></el-icon>
            </div>
          </div>
        </div>
      </el-collapse-transition>
    </div>
  </div>

  <!-- 查看展示模块 -->
  <div class="wrap2" v-else>
    <div class="wrap2_ul" v-if="fileList && fileList.length > 0">
      <el-popover placement="top-start" :width="300" trigger="hover" v-if="fileList.length > 1">
        <div v-for="(item, i) in fileList" :key="i">
          <a class="downBox" :href="isDownload ? getFileBucketDirObject(item.meta.dir, item.meta.name) : 'javascript:void(0);'">{{ item.object }}</a>
        </div>
        <template #reference>
          <span class="el-dropdown-link">{{t('keys.Detail')}}（{{ fileList.length }}）</span>
        </template>
      </el-popover>
      <span v-else>
        <a
          class="el-dropdown-link"
          :href="isDownload ? getFileBucketDirObject(fileList[0].meta.dir, fileList[0].meta.name) : 'javascript:void(0);'"
          >{{ fileList[0].object }}</a
        ></span
      >
      <!-- <template v-for="(item, i) in fileList" :key="i" v-if="fileList.length <=1 || loadMore">
        <a
          class="wrap2_li"
          
         
          :href="isDownload ? getFileBucketDirObject(item.meta.dir, item.meta.name) : 'javascript:void(0);'"
          >{{ item.object }}</a
        >
      </template>

      <a class="wrap2_li" v-if="fileList.length > 1 && !loadMore" @click="loadMore = true">查看更多({{ fileList.length }})</a> -->
    </div>
  </div>
  <status-bar :uppy="uppy" style="display: none" />
</template>
<script setup>
/* eslint-disable */
import { ref, reactive, onBeforeUnmount, unref, onMounted, onActivated, nextTick, computed, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { getFileBucketApi, getFileBucketDirobject, getFileBucketDirlist, getFileBucketDirdele } from 'api/common'
import Uppy from '@uppy/core'
import Tus from '@uppy/tus'
import { getDir, bucket, uploadFile } from '@/api/uploadFile'
import { BASE_URL } from 'config/constant'
import { StatusBar } from '@uppy/vue'
import { getTenantId, getTokenType, getAccessToken } from 'utils/headerToken'
import { ERR_OK } from 'config/statusCode'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const uppy = new Uppy()
// folderDir目录名 fileList文件列表
// 方法：onChange （ folderDir.value, fileList.value）=> 点击上传按钮事件   onUpload （ folderDir.value, fileList.value）=> 上传开始回调  onComplete （ folderDir.value, fileList.value） => 上传完成
const props = defineProps({
  fileSize: {
    // 单位M 单个最大50M
    type: Number,
    default: 50
  },
  fileType: {
    // 上传文件的格式 ['xlsx', 'xls']
    type: Array,
    default: () => []
  },
  value: {
    type: String,
    default: ''
  },
  limit: {
    // 最大上传数量
    type: Number,
    default: 10000
  },
  isExhibition: {
    // 是否是展示查看
    type: Boolean,
    default: false
  },
  disabled: {
    type: Boolean,
    default: false
  },
  isDownload: {
    // 是否是可以下载（配合isExhibition使用）
    type: Boolean,
    default: false
  },
  isTableLine: {
    // 是否是表格行内上传
    type: Boolean,
    default: false
  }
})
const emit = defineEmits(['onUpload', 'onComplete', 'onChange'])
const folderDir = ref(props.value) // folderDir: value, // folderDir文件名 说明编辑编辑) // folderDir: value, // folderDir文件名 说明编辑编辑
watch(
  props.value,
  (val) => {
    nextTick(() => {
      if (val) folderDir.value = val
    })
  },
  {
    immediate: true,
    deep: true
  }
)
const loadMore = ref(false)
const actionUrl = `${BASE_URL}/zfil/v1/${getTenantId()}/tus?access_token=${getAccessToken()}`
const loadingFlag = ref(false)
const fileNametager = ref('')
const fileList = ref([])
const fileNum = ref('')
const MathNum = ref('')
const wraprWidth = ref('100%')
const fileInput = ref(null)
const wrapRef = ref(null)
const wraplRef = ref(null)

onMounted(() => {
  // uppy = new Uppy()
  MathNum.value = Math.round(Math.random() * 1000)
  props.isExhibition ? props.isExhibition : init()

  nextTick(() => {
    // onActivated 调用失效
    setTimeout(() => {
      if (props.value) {
        getFileBucketDirList(props.value) //  dir 获取目录内文件集合
      }
      // else {
      //   getFileBucket()
      // }
    }, 200)
    if (!props.isExhibition && unref(wrapRef).clientWidth && unref(wraplRef).clientWidth) {
      wraprWidth.value = unref(wrapRef).clientWidth - unref(wraplRef).clientWidth - 8 + 'px'
    }
  })
})

// onActivated(() => {
//   props.isExhibition ? '' : closeUppy() // 清楚缓存
//   // 有folderDir文件名 说明编辑编辑
//   if (props.value) {
//     getFileBucketDirList(props.value) //  dir 获取目录内文件集合
//   }

//   nextTick(() => {
//     if (!props.isExhibition && unref(wrapRef).clientWidth && unref(wraplRef).clientWidth) {
//       wraprWidth.value = unref(wrapRef).clientWidth - unref(wraplRef).clientWidth - 8 + 'px'
//     }
//   })
// })
// 实例销毁之前对点击事件进行解绑
onBeforeUnmount(() => {
  fileInput.value = null // 下拉框点击
  uppy.close()
})
const showList = ref([])
const overShow = () => {
  showList.value = true
}
const outHide = () => {
  showList.value = false
}

const init = () => {
  uppy.setOptions({
    debug: true,
    autoProceed: true,
    showProgressDetails: true,
    restrictions: {
      maxFileSize: 100 * 1024 * 1024
    }
  })
  uppy.use(Tus, {
    endpoint: actionUrl, // 在这里使用您的tus接口
    // resume: that,
    retryDelays: null,
    chunkSize: 5 * 1024 * 1024
  })
  nextTick(() => {
    fileInput.value = document.querySelector('#fileInputBtn' + MathNum.value)
    fileInput.value.addEventListener('change', (event) => {
      let uppName = event.target?.files[0]?.name || ''
      var extensions = props.fileType // 判断上传图片的格式 上传文件的格式 ['xlsx', 'xls']
      var extension = uppName.substr(uppName.lastIndexOf('.') + 1)
      var extOk = !!extensions.find((item) => item === extension.toLowerCase())
      if (!extOk && extensions.length > 0) {
        fileInput.value = null
        ElMessage.warning(`${t('keys.upload_format')}${JSON.stringify(extensions.join('、'))}${t('keys.upload_format_1')}!`)
        return false
      }

      // 图片上传大小
      let eventSize = event.target.files[0].size || ''
      var isLt2M = eventSize / 1024 / 1024 < (props.fileSize >= 50 ? 50 : props.fileSize)
      if (!isLt2M) {
        fileInput.value = null
        ElMessage.warning(`${t('keys.uploadfileSize')}"${props.fileSize >= 50 ? 50 : props.fileSize}"M`)
        return
      }

      // 文件已存在, 请重命名文件
      let uppnameList = fileList.value.filter(function(ele) {
        // 成功的list
        return ele.name == uppName
      })

      if (uppnameList.length > 0) {
        fileInput.value = null
        ElMessage.warning(`"${uppName}" ${t('keys.have_upload_file')}!`)
        return
      }

      if (folderDir.value) {
        initData(uppy, event)
      } else {
        getFileBucketApi().then((res) => {
          if (res.code === ERR_OK) {
            folderDir.value = res.data.name
            initData(uppy, event)
          }
        })
      }
    })
    // 上传开始时触发。
    uppy.on('upload', (res) => {
      fileInput.value = null
      loadingFlag.value = true
      fileNametager.value = ''
      let uppylist
      uppylist = uppy.getFiles().filter(function(ele) {
        // 成功的list
        return ele.id == res.fileIDs[0]
      })
      uppylist.forEach((value) => {
        value.loadingIconFlag = true // 是否显示loading
        value.downloadIconFlag = false // 是否显示下载icon
        value.uploadFlag = false // 重新上传
        value.deleIconFlag = false // 是否显示删除icon
      })

      fileList.value = [...uppylist, ...fileList.value]
      emit('onUpload', folderDir.value, fileList.value) // 上传开始回调
    })
    // 在所有上载完成时激发。
    uppy.on('complete', (file) => {
      fileInput.value = null
      fileList.value.forEach((value) => {
        value.loadingIconFlag = false // 是否显示loading
        if (file.failed.length && value.id == file.failed[0].id) {
          value.downloadIconFlag = false // 是否显示下载icon
          value.deleIconFlag = true // 是否显示删除icon
          value.uploadFlag = true // 重新上传
          if (file.failed[0].error && getParenthesesStr(file.failed[0].error)) {
            let errorBody = JSON.parse('{' + getParenthesesStr(file.failed[0].error) + '}')
            if (errorBody && errorBody?.code == '-1' && errorBody?.desc) {
              ElMessage.error(errorBody.desc)
            } else {
              ElMessage.error(`${file.failed[0].name}${t('keys.upload_failed')}！`)
            }
          } else {
            ElMessage.error(`${file.failed[0].name}${t('keys.upload_failed')}！`)
          }
        } else {
          if (!value.uploadFlag) {
            value.downloadIconFlag = true // 是否显示下载icon
            value.deleIconFlag = true // 是否显示删除icon
          }
        }
      })
      // 成功的list
      fileNum.value = fileList.value.filter(function(ele) {
        return !ele.uploadFlag
      })
      loadingFlag.value = false
      fileInput.value = null
      showList.value = false
      emit('onComplete', folderDir.value, fileList.value)
    })
  })
}

const getParenthesesStr = (text) => {
  //截取括号中的字符串
  var result = ''
  if (text) {
    var regex = /{(.+?)}/g
    var options = text.match(regex)
    if (options) {
      var option = options[0]
      if (options) {
        result = option.substring(1, option.length - 1)
      }
    }
  }
  return result
}
const getFileBucket = () => {
  getFileBucketApi().then((res) => {
    if (res.code === ERR_OK) {
      folderDir.value = res.data.name
      initData(uppy, event)
    }
  })
}
const initData = (uppy, event) => {
  uppy.setOptions({
    meta: { dir: folderDir.value } // dir文件夹名
  })
  const files = Array.from(event.target.files)
  files.forEach((file) => {
    try {
      emit('onChange', folderDir.value, fileList.value)
      uppy.addFile({
        source: 'file input',
        name: file.name,
        type: file.type,
        data: file
      })

      fileNametager.value = file.name
    } catch (err) {
      fileInput.value = null
      if (err.isRestriction) {
        // 处理限制
        ElMessage.error(err)
      } else {
        // 处理其他错误
      }
    }
  })
}
// const clickOther = () => {
//   showList.value = false
// }
const closeUppy = () => {
  // 清理localstorage
  const len = localStorage.length
  const arr = []
  for (var i = 0; i < len; i++) {
    // 获取key 索引从0开始
    const key = localStorage.key(i)
    // 检查是否是tus开头的key, 是则加入记录
    if (key && key.indexOf('tus::') !== -1) {
      arr.push(key)
    }
  }
  for (let e of arr) {
    localStorage.removeItem(e)
  }
  // 清理缓存
  uppy.reset()
}
// 文件下载链接
const getFileBucketDirObject = (dir, object) => {
  return getFileBucketDirobject(dir, object)
}
const getUploadFileUrl = async () => {
  let res = await getFileBucketApi()
  if (res.data.name) {
    dataObj.uploadFileUrl = uploadFile(res.data.name)
  } else {
    let resObj = bucket(localStorage.getItem('tenantId'))
    dataObj.uploadFileUrl = uploadFile(resObj.data.name)
  }
}
const getFileBucketDirList = (dir) => {
  // 根据目录名dir 获取文件列表
  if (dir) {
    folderDir.value = dir
  }
  getFileBucketDirlist(folderDir.value).then((res) => {
    if (res.code === ERR_OK) {
      fileList.value = res.data || []
      fileList.value.forEach((value) => {
        value.meta = { dir: value.dir, name: value.object }
        value.name = value.object
        value.loadingIconFlag = false // 是否显示loading
        value.downloadIconFlag = true // 是否显示下载icon
        value.deleIconFlag = true // 是否显示删除icon
        value.uploadFlag = false // 重新上传
      })
      fileNum.value = fileList.value.filter(function(ele) {
        // 成功的list
        return !ele.uploadFlag
      })
      if (fileList.value.length == 0) {
        closeUppy() // 清除缓存
      }
    }
  })
}
const getFileBucketDirDele = (item) => {
  // 删除文件
  uppy.removeFile(item.id || item.guid)
  item.id = item.id || item.guid
  if (!item.uploadFlag) {
    getFileBucketDirdele(item.meta.dir, item.meta.name).then((res) => {
      if (res.code === ERR_OK) {
        fileList.value = fileList.value.filter(function(ele) {
          return ele.id != item.id
        })
        fileList.value = fileList.value
        fileNum.value = fileList.value.filter(function(ele) {
          // 成功的list
          return !ele.uploadFlag
        })
      }
    })
  } else {
    fileList.value = fileList.value.filter(function(ele) {
      return ele.id != item.id
    })
    fileList.value = fileList.value
    fileNum.value = fileList.value.filter(function(ele) {
      // 成功的list
      return !ele.uploadFlag
    })
  }
}
const uploadClick = (item) => {
  // 重新上传
  fileList.value = fileList.value.filter(function(ele) {
    return ele.id != item.id
  })
  uppy.retryUpload(item.id)
}
</script>

<style lang="scss" scoped>
.wrap {
  width: 100%;
  line-height: 32px;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  .wrap_l {
    width: 90px;
    height: 32px;
    position: relative;
    cursor: pointer;
    .fileInput {
      position: absolute;
      top: 0;
      left: 0;
      width: 90px;
      height: 32px;
      opacity: 0;
      font-size: 0;
      cursor: pointer;
    }
    .porfileInput {
      position: fixed;
      top: 100000000000000000000px;
      left: 100000000000000000000000px;
    }
    .disabbtn {
      width: 90px;
      height: 32px;
      // position: absolute;
      top: 0;
      left: 0;
      z-index: 1;
    }
  }
  .wrap_r {
    // max-width: 260px;
    flex-grow: 1;
    margin-left: 8px;
    display: flex;
    flex-direction: column;
    cursor: pointer;
    position: relative;
    .singleGroup {
      width: 100%;
      flex-grow: 1;
      display: flex;
      flex-direction: row;
      align-items: center;
      justify-content: space-between;
      .singleGroup_l {
        width: 70%;
        height: 32px;
        margin-left: 8px;
        white-space: nowrap; //不换行
        overflow: hidden; //超出隐藏
        text-overflow: ellipsis; //变成...
      }
      .singleGroup_r {
        margin-right: 8px;
        display: none;
        i {
          margin-left: 12px;
          color: #cccccc;
          cursor: pointer;
        }
        .dele {
          color: #e43623;
        }
      }
      .showsingleGroup {
        display: block;
      }
    }
    // 多条样式
    .inputtxt {
      // width: 260px;
      height: 30px;
      line-height: 30px;
      font-size: 14px;
      color: #333333;
      background: #ffffff;
      border-radius: 2px;
      border: 1px solid #d6d6d6;
      display: flex;
      flex-direction: row;
      align-items: center;
      justify-content: space-between;
      .inputtxt_l {
        margin-left: 12px;
        margin-right: 4px;
        max-width: 70%;
        height: 32px;
        white-space: nowrap; //不换行
        overflow: hidden; //超出隐藏
        text-overflow: ellipsis; //变成...
        display: inline-block;
      }
      .inputtxt_r {
        width: 30px;
        display: flex;
        text-align: center;
        flex-direction: row;
        justify-content: center;
        .inputtxt_r_icon {
          color: #ccc;
          font-size: 14px;
          transition: transform 0.3s;
          transform: rotateZ(180deg);
          cursor: pointer;
          vertical-align: bottom;
        }
        .inputtxt_r_icon.isReverse {
          transform: rotateZ(0);
        }
      }
    }
    .ullist {
      position: absolute;
      top: 40px;
      left: 0px;
      background: #ffffff;
      border-radius: 2px;
      width: 100%;
      z-index: 999;
      box-shadow: 0px 1px 6px rgba(0, 0, 0, 0.3);
    }

    // .singleGroup:not(:last-child):hover {
    //   background: #f5f5f5;
    // }
    .singleGroup:hover {
      background: #f5f5f5;
    }
    .singleGroup:hover .singleGroup_r {
      display: flex;
      align-items: center;
    }
    .errcolor {
      color: #e43623 !important;
    }
  }
}
.uppy-StatusBar,
.hideinput {
  display: none;
}
.wrap2 {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  .wrap2_li {
    width: 100%;
    color: var(--el-menu-active-color);
    cursor: pointer;
    font-size: 14px;
    height: 30px;
    line-height: 30px;
    display: block;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    text-overflow: ellipsis;
  }
}

/*包含以下四种的链接*/
a {
  margin-top: 4px;
  text-decoration: none;
}

/*正常的未被访问过的链接*/
a:link {
  text-decoration: none;
}

/*已经访问过的链接*/
a:visited {
  text-decoration: none;
}

/*鼠标划过(停留)的链接*/
a:hover {
  text-decoration: none;
}

/* 正在点击的链接*/
a:active {
  text-decoration: none;
}
.el-dropdown-link {
  line-height: 23px;
  color: var(--el-color-primary);
}
.downBox {
  cursor: pointer;
}
.downBox:hover {
  color: var(--el-color-primary);
}
.wrap_lnone {
  display: none;
}
</style>
